home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / gnu / libg_261.zip / libg_261 / libg++ / src / Integer.cc < prev    next >
C/C++ Source or Header  |  1994-05-11  |  47KB  |  2,281 lines

  1. /* 
  2. Copyright (C) 1988 Free Software Foundation
  3.     written by Doug Lea (dl@rocky.oswego.edu)
  4.  
  5. This file is part of the GNU C++ Library.  This library is free
  6. software; you can redistribute it and/or modify it under the terms of
  7. the GNU Library General Public License as published by the Free
  8. Software Foundation; either version 2 of the License, or (at your
  9. option) any later version.  This library is distributed in the hope
  10. that it will be useful, but WITHOUT ANY WARRANTY; without even the
  11. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  12. PURPOSE.  See the GNU Library General Public License for more details.
  13. You should have received a copy of the GNU Library General Public
  14. License along with this library; if not, write to the Free Software
  15. Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  16. */
  17.  
  18. /*
  19.   Some of the following algorithms are very loosely based on those from 
  20.   MIT C-Scheme bignum.c, which is
  21.       Copyright (c) 1987 Massachusetts Institute of Technology
  22.  
  23.   with other guidance from Knuth, vol. 2
  24.  
  25.   Thanks to the creators of the algorithms.
  26. */
  27.  
  28. #ifdef __GNUG__
  29. #pragma implementation
  30. #endif
  31. #include <Integer.h>
  32. #include <std.h>
  33. #include <ctype.h>
  34. #include <limits.h>
  35. #include <Obstack.h>
  36. #include <AllocRing.h>
  37. #include <new.h>
  38. #include <builtin.h>
  39. #include "Integer.hP"
  40.  
  41. IntRep _ZeroRep = {1, 0, 1, {0}};
  42. IntRep _OneRep = {1, 0, 1, {1}};
  43. IntRep _MinusOneRep = {1, 0, 0, {1}};
  44.  
  45.  
  46. // utilities to extract and transfer bits 
  47.  
  48. // get low bits
  49.  
  50. inline static unsigned short extract(unsigned long x)
  51. {
  52.   return x & I_MAXNUM;
  53. }
  54.  
  55. // transfer high bits to low
  56.  
  57. inline static unsigned long down(unsigned long x)
  58. {
  59.   return (x >> I_SHIFT) & I_MAXNUM;
  60. }
  61.  
  62. // transfer low bits to high
  63.  
  64. inline static unsigned long up(unsigned long x)
  65. {
  66.   return x << I_SHIFT;
  67. }
  68.  
  69. // compare two equal-length reps
  70.  
  71. inline static int docmp(const unsigned short* x, const unsigned short* y, int l)
  72. {
  73.   int diff = 0;
  74.   const unsigned short* xs = &(x[l]);
  75.   const unsigned short* ys = &(y[l]);
  76.   while (l-- > 0 && (diff = (*--xs) - (*--ys)) == 0);
  77.   return diff;
  78. }
  79.  
  80. // figure out max length of result of +, -, etc.
  81.  
  82. inline static int calc_len(int len1, int len2, int pad)
  83. {
  84.   return (len1 >= len2)? len1 + pad : len2 + pad;
  85. }
  86.  
  87. // ensure len & sgn are correct
  88.  
  89. inline static void Icheck(IntRep* rep)
  90. {
  91.   int l = rep->len;
  92.   const unsigned short* p = &(rep->s[l]);
  93.   while (l > 0 && *--p == 0) --l;
  94.   if ((rep->len = l) == 0) rep->sgn = I_POSITIVE;
  95. }
  96.  
  97.  
  98. // zero out the end of a rep
  99.  
  100. inline static void Iclear_from(IntRep* rep, int p)
  101. {
  102.   unsigned short* cp = &(rep->s[p]);
  103.   const unsigned short* cf = &(rep->s[rep->len]);
  104.   while(cp < cf) *cp++ = 0;
  105. }
  106.  
  107. // copy parts of a rep
  108.  
  109. static inline void scpy(const unsigned short* src, unsigned short* dest,int nb)
  110. {
  111.   while (--nb >= 0) *dest++ = *src++;
  112. }
  113.  
  114. // make sure an argument is valid
  115.  
  116. static inline void nonnil(const IntRep* rep)
  117. {
  118.   if (rep == 0) 
  119.     (*lib_error_handler)("Integer", "operation on uninitialized Integer");
  120. }
  121.  
  122. // allocate a new Irep. Pad to something close to a power of two.
  123.  
  124. inline static IntRep* Inew(int newlen)
  125. {
  126.   unsigned int siz = sizeof(IntRep) + newlen * sizeof(short) + 
  127.     MALLOC_MIN_OVERHEAD;
  128.   unsigned int allocsiz = MINIntRep_SIZE;
  129.   while (allocsiz < siz) allocsiz <<= 1;  // find a power of 2
  130.   allocsiz -= MALLOC_MIN_OVERHEAD;
  131.   if (allocsiz >= MAXIntRep_SIZE * sizeof(short))
  132.     (*lib_error_handler)("Integer", "Requested length out of range");
  133.     
  134.   IntRep* rep = (IntRep *) new char[allocsiz];
  135.   rep->sz = (allocsiz - sizeof(IntRep) + sizeof(short)) / sizeof(short);
  136.   return rep;
  137. }
  138.  
  139. // allocate: use the bits in src if non-null, clear the rest
  140.  
  141. IntRep* Ialloc(IntRep* old, const unsigned short* src, int srclen, int newsgn,
  142.               int newlen)
  143. {
  144.   IntRep* rep;
  145.   if (old == 0 || newlen > old->sz)
  146.     rep = Inew(newlen);
  147.   else
  148.     rep = old;
  149.  
  150.   rep->len = newlen;
  151.   rep->sgn = newsgn;
  152.  
  153.   scpy(src, rep->s, srclen);
  154.   Iclear_from(rep, srclen);
  155.  
  156.   if (old != rep && old != 0 && !STATIC_IntRep(old)) delete old;
  157.   return rep;
  158. }
  159.  
  160. // allocate and clear
  161.  
  162. IntRep* Icalloc(IntRep* old, int newlen)
  163. {
  164.   IntRep* rep;
  165.   if (old == 0 || newlen > old->sz)
  166.   {
  167.     if (old != 0 && !STATIC_IntRep(old)) delete old;
  168.     rep = Inew(newlen);
  169.   }
  170.   else
  171.     rep = old;
  172.  
  173.   rep->len = newlen;
  174.   rep->sgn = I_POSITIVE;
  175.   Iclear_from(rep, 0);
  176.  
  177.   return rep;
  178. }
  179.  
  180. // reallocate
  181.  
  182. IntRep* Iresize(IntRep* old, int newlen)
  183. {
  184.   IntRep* rep;
  185.   unsigned short oldlen;
  186.   if (old == 0)
  187.   {
  188.     oldlen = 0;
  189.     rep = Inew(newlen);
  190.     rep->sgn = I_POSITIVE;
  191.   }
  192.   else 
  193.   {
  194.     oldlen = old->len;
  195.     if (newlen > old->sz)
  196.     {
  197.       rep = Inew(newlen);
  198.       scpy(old->s, rep->s, oldlen);
  199.       rep->sgn = old->sgn;
  200.       if (!STATIC_IntRep(old)) delete old;
  201.     }
  202.     else
  203.       rep = old;
  204.   }
  205.  
  206.   rep->len = newlen;
  207.   Iclear_from(rep, oldlen);
  208.  
  209.   return rep;
  210. }
  211.  
  212.  
  213. // same, for straight copy
  214.  
  215. IntRep* Icopy(IntRep* old, const IntRep* src)
  216. {
  217.   if (old == src) return old; 
  218.   IntRep* rep;
  219.   if (src == 0)
  220.   {
  221.     if (old == 0)
  222.       rep = Inew(0);
  223.     else
  224.     {
  225.       rep = old;
  226.       Iclear_from(rep, 0);
  227.     }
  228.     rep->len = 0;
  229.     rep->sgn = I_POSITIVE;
  230.   }
  231.   else 
  232.   {
  233.     int newlen = src->len;
  234.     if (old == 0 || newlen > old->sz)
  235.     {
  236.       if (old != 0 && !STATIC_IntRep(old)) delete old;
  237.       rep = Inew(newlen);
  238.     }
  239.     else
  240.       rep = old;
  241.  
  242.     rep->len = newlen;
  243.     rep->sgn = src->sgn;
  244.  
  245.     scpy(src->s, rep->s, newlen);
  246.   }
  247.  
  248.   return rep;
  249. }
  250.  
  251. // allocate & copy space for a long
  252.  
  253. IntRep* Icopy_long(IntRep* old, long x)
  254. {
  255.   int newsgn = (x >= 0);
  256.   IntRep* rep = Icopy_ulong(old, newsgn ? x : -x);
  257.   rep->sgn = newsgn;
  258.   return rep;
  259. }
  260.  
  261. IntRep* Icopy_ulong(IntRep* old, unsigned long x)
  262. {
  263.   unsigned short src[SHORT_PER_LONG];
  264.   
  265.   unsigned short srclen = 0;
  266.   while (x != 0)
  267.   {
  268.     src[srclen++] = extract(x);
  269.     x = down(x);
  270.   }
  271.  
  272.   IntRep* rep;
  273.   if (old == 0 || srclen > old->sz)
  274.   {
  275.     if (old != 0 && !STATIC_IntRep(old)) delete old;
  276.     rep = Inew(srclen);
  277.   }
  278.   else
  279.     rep = old;
  280.  
  281.   rep->len = srclen;
  282.   rep->sgn = I_POSITIVE;
  283.  
  284.   scpy(src, rep->s, srclen);
  285.  
  286.   return rep;
  287. }
  288.  
  289. // special case for zero -- it's worth it!
  290.  
  291. IntRep* Icopy_zero(IntRep* old)
  292. {
  293.   if (old == 0 || STATIC_IntRep(old))
  294.     return &_ZeroRep;
  295.  
  296.   old->len = 0;
  297.   old->sgn = I_POSITIVE;
  298.  
  299.   return old;
  300. }
  301.  
  302. // special case for 1 or -1
  303.  
  304. IntRep* Icopy_one(IntRep* old, int newsgn)
  305. {
  306.   if (old == 0 || 1 > old->sz)
  307.   {
  308.     if (old != 0 && !STATIC_IntRep(old)) delete old;
  309.     return newsgn==I_NEGATIVE ? &_MinusOneRep : &_OneRep;
  310.   }
  311.  
  312.   old->sgn = newsgn;
  313.   old->len = 1;
  314.   old->s[0] = 1;
  315.  
  316.   return old;
  317. }
  318.  
  319. // convert to a legal two's complement long if possible
  320. // if too big, return most negative/positive value
  321.  
  322. long Itolong(const IntRep* rep)
  323.   if ((unsigned)(rep->len) > (unsigned)(SHORT_PER_LONG))
  324.     return (rep->sgn == I_POSITIVE) ? LONG_MAX : LONG_MIN;
  325.   else if (rep->len == 0)
  326.     return 0;
  327.   else if ((unsigned)(rep->len) < (unsigned)(SHORT_PER_LONG))
  328.   {
  329.     unsigned long a = rep->s[rep->len-1];
  330.     if (SHORT_PER_LONG > 2) // normally optimized out
  331.     {
  332.       for (int i = rep->len - 2; i >= 0; --i)
  333.         a = up(a) | rep->s[i];
  334.     }
  335.     return (rep->sgn == I_POSITIVE)? a : -((long)a);
  336.   }
  337.   else 
  338.   {
  339.     unsigned long a = rep->s[SHORT_PER_LONG - 1];
  340.     if (a >= I_MINNUM)
  341.       return (rep->sgn == I_POSITIVE) ? LONG_MAX : LONG_MIN;
  342.     else
  343.     {
  344.       a = up(a) | rep->s[SHORT_PER_LONG - 2];
  345.       if (SHORT_PER_LONG > 2)
  346.       {
  347.         for (int i = SHORT_PER_LONG - 3; i >= 0; --i)
  348.           a = up(a) | rep->s[i];
  349.       }
  350.       return (rep->sgn == I_POSITIVE)? a : -((long)a);
  351.     }
  352.   }
  353. }
  354.  
  355. // test whether op long() will work.
  356. // careful about asymmetry between LONG_MIN & LONG_MAX
  357.  
  358. int Iislong(const IntRep* rep)
  359. {
  360.   unsigned int l = rep->len;
  361.   if (l < SHORT_PER_LONG)
  362.     return 1;
  363.   else if (l > SHORT_PER_LONG)
  364.     return 0;
  365.   else if ((unsigned)(rep->s[SHORT_PER_LONG - 1]) < (unsigned)(I_MINNUM))
  366.     return 1;
  367.   else if (rep->sgn == I_NEGATIVE && rep->s[SHORT_PER_LONG - 1] == I_MINNUM)
  368.   {
  369.     for (unsigned int i = 0; i < SHORT_PER_LONG - 1; ++i)
  370.       if (rep->s[i] != 0)
  371.         return 0;
  372.     return 1;
  373.   }
  374.   else
  375.     return 0;
  376. }
  377.  
  378. // comparison functions
  379.   
  380. int compare(const IntRep* x, const IntRep* y)
  381. {
  382.   int diff  = x->sgn - y->sgn;
  383.   if (diff == 0)
  384.   {
  385.     diff = x->len - y->len;
  386.     if (diff == 0)
  387.       diff = docmp(x->s, y->s, x->len);
  388.     if (x->sgn == I_NEGATIVE)
  389.       diff = -diff;
  390.   }
  391.   return diff;
  392. }
  393.  
  394. int ucompare(const IntRep* x, const IntRep* y)
  395. {
  396.   int diff = x->len - y->len;
  397.   if (diff == 0)
  398.   {
  399.     int l = x->len;
  400.     const unsigned short* xs = &(x->s[l]);
  401.     const unsigned short* ys = &(y->s[l]);
  402.     while (l-- > 0 && (diff = (*--xs) - (*--ys)) == 0);
  403.   }
  404.   return diff;
  405. }
  406.  
  407. int compare(const IntRep* x, long  y)
  408. {
  409.   int xl = x->len;
  410.   int xsgn = x->sgn;
  411.   if (y == 0)
  412.   {
  413.     if (xl == 0)
  414.       return 0;
  415.     else if (xsgn == I_NEGATIVE)
  416.       return -1;
  417.     else
  418.       return 1;
  419.   }
  420.   else
  421.   {
  422.     int ysgn = y >= 0;
  423.     unsigned long uy = (ysgn)? y : -y;
  424.     int diff = xsgn - ysgn;
  425.     if (diff == 0)
  426.     {
  427.       diff = xl - SHORT_PER_LONG;
  428.       if (diff <= 0)
  429.       {
  430.         unsigned short tmp[SHORT_PER_LONG];
  431.         int yl = 0;
  432.         while (uy != 0)
  433.         {
  434.           tmp[yl++] = extract(uy);
  435.           uy = down(uy);
  436.         }
  437.         diff = xl - yl;
  438.         if (diff == 0)
  439.           diff = docmp(x->s, tmp, xl);
  440.       }
  441.       if (xsgn == I_NEGATIVE)
  442.     diff = -diff;
  443.     }
  444.     return diff;
  445.   }
  446. }
  447.  
  448. int ucompare(const IntRep* x, long  y)
  449. {
  450.   int xl = x->len;
  451.   if (y == 0)
  452.     return xl;
  453.   else
  454.   {
  455.     unsigned long uy = (y >= 0)? y : -y;
  456.     int diff = xl - SHORT_PER_LONG;
  457.     if (diff <= 0)
  458.     {
  459.       unsigned short tmp[SHORT_PER_LONG];
  460.       int yl = 0;
  461.       while (uy != 0)
  462.       {
  463.         tmp[yl++] = extract(uy);
  464.         uy = down(uy);
  465.       }
  466.       diff = xl - yl;
  467.       if (diff == 0)
  468.         diff = docmp(x->s, tmp, xl);
  469.     }
  470.     return diff;
  471.   }
  472. }
  473.  
  474.  
  475.  
  476. // arithmetic functions
  477.  
  478. IntRep* add(const IntRep* x, int negatex, 
  479.             const IntRep* y, int negatey, IntRep* r)
  480. {
  481.   nonnil(x);
  482.   nonnil(y);
  483.  
  484.   int xl = x->len;
  485.   int yl = y->len;
  486.  
  487.   int xsgn = (negatex && xl != 0) ? !x->sgn : x->sgn;
  488.   int ysgn = (negatey && yl != 0) ? !y->sgn : y->sgn;
  489.  
  490.   int xrsame = x == r;
  491.   int yrsame = y == r;
  492.  
  493.   if (yl == 0)
  494.     r = Ialloc(r, x->s, xl, xsgn, xl);
  495.   else if (xl == 0)
  496.     r = Ialloc(r, y->s, yl, ysgn, yl);
  497.   else if (xsgn == ysgn)
  498.   {
  499.     if (xrsame || yrsame)
  500.       r = Iresize(r, calc_len(xl, yl, 1));
  501.     else
  502.       r = Icalloc(r, calc_len(xl, yl, 1));
  503.     r->sgn = xsgn;
  504.     unsigned short* rs = r->s;
  505.     const unsigned short* as;
  506.     const unsigned short* bs;
  507.     const unsigned short* topa;
  508.     const unsigned short* topb;
  509.     if (xl >= yl)
  510.     {
  511.       as =  (xrsame)? r->s : x->s;
  512.       topa = &(as[xl]);
  513.       bs =  (yrsame)? r->s : y->s;
  514.       topb = &(bs[yl]);
  515.     }
  516.     else
  517.     {
  518.       bs =  (xrsame)? r->s : x->s;
  519.       topb = &(bs[xl]);
  520.       as =  (yrsame)? r->s : y->s;
  521.       topa = &(as[yl]);
  522.     }
  523.     unsigned long sum = 0;
  524.     while (bs < topb)
  525.     {
  526.       sum += (unsigned long)(*as++) + (unsigned long)(*bs++);
  527.       *rs++ = extract(sum);
  528.       sum = down(sum);
  529.     }
  530.     while (sum != 0 && as < topa)
  531.     {
  532.       sum += (unsigned long)(*as++);
  533.       *rs++ = extract(sum);
  534.       sum = down(sum);
  535.     }
  536.     if (sum != 0)
  537.       *rs = extract(sum);
  538.     else if (rs != as)
  539.       while (as < topa)
  540.         *rs++ = *as++;
  541.   }
  542.   else
  543.   {
  544.     int comp = ucompare(x, y);
  545.     if (comp == 0)
  546.       r = Icopy_zero(r);
  547.     else
  548.     {
  549.       if (xrsame || yrsame)
  550.         r = Iresize(r, calc_len(xl, yl, 0));
  551.       else
  552.         r = Icalloc(r, calc_len(xl, yl, 0));
  553.       unsigned short* rs = r->s;
  554.       const unsigned short* as;
  555.       const unsigned short* bs;
  556.       const unsigned short* topa;
  557.       const unsigned short* topb;
  558.       if (comp > 0)
  559.       {
  560.         as =  (xrsame)? r->s : x->s;
  561.         topa = &(as[xl]);
  562.         bs =  (yrsame)? r->s : y->s;
  563.         topb = &(bs[yl]);
  564.         r->sgn = xsgn;
  565.       }
  566.       else
  567.       {
  568.         bs =  (xrsame)? r->s : x->s;
  569.         topb = &(bs[xl]);
  570.         as =  (yrsame)? r->s : y->s;
  571.         topa = &(as[yl]);
  572.         r->sgn = ysgn;
  573.       }
  574.       unsigned long hi = 1;
  575.       while (bs < topb)
  576.       {
  577.         hi += (unsigned long)(*as++) + I_MAXNUM - (unsigned long)(*bs++);
  578.         *rs++ = extract(hi);
  579.         hi = down(hi);
  580.       }
  581.       while (hi == 0 && as < topa)
  582.       {
  583.         hi = (unsigned long)(*as++) + I_MAXNUM;
  584.         *rs++ = extract(hi);
  585.         hi = down(hi);
  586.       }
  587.       if (rs != as)
  588.         while (as < topa)
  589.           *rs++ = *as++;
  590.     }
  591.   }
  592.   Icheck(r);
  593.   return r;
  594. }
  595.  
  596.  
  597. IntRep* add(const IntRep* x, int negatex, long y, IntRep* r)
  598. {
  599.   nonnil(x);
  600.   int xl = x->len;
  601.   int xsgn = (negatex && xl != 0) ? !x->sgn : x->sgn;
  602.   int xrsame = x == r;
  603.  
  604.   int ysgn = (y >= 0);
  605.   unsigned long uy = (ysgn)? y : -y;
  606.  
  607.   if (y == 0)
  608.     r = Ialloc(r, x->s, xl, xsgn, xl);
  609.   else if (xl == 0)
  610.     r = Icopy_long(r, y);
  611.   else if (xsgn == ysgn)
  612.   {
  613.     if (xrsame)
  614.       r = Iresize(r, calc_len(xl, SHORT_PER_LONG, 1));
  615.     else
  616.       r = Icalloc(r, calc_len(xl, SHORT_PER_LONG, 1));
  617.     r->sgn = xsgn;
  618.     unsigned short* rs = r->s;
  619.     const unsigned short* as =  (xrsame)? r->s : x->s;
  620.     const unsigned short* topa = &(as[xl]);
  621.     unsigned long sum = 0;
  622.     while (as < topa && uy != 0)
  623.     {
  624.       unsigned long u = extract(uy);
  625.       uy = down(uy);
  626.       sum += (unsigned long)(*as++) + u;
  627.       *rs++ = extract(sum);
  628.       sum = down(sum);
  629.     }
  630.     while (sum != 0 && as < topa)
  631.     {
  632.       sum += (unsigned long)(*as++);
  633.       *rs++ = extract(sum);
  634.       sum = down(sum);
  635.     }
  636.     if (sum != 0)
  637.       *rs = extract(sum);
  638.     else if (rs != as)
  639.       while (as < topa)
  640.         *rs++ = *as++;
  641.   }
  642.   else
  643.   {
  644.     unsigned short tmp[SHORT_PER_LONG];
  645.     int yl = 0;
  646.     while (uy != 0)
  647.     {
  648.       tmp[yl++] = extract(uy);
  649.       uy = down(uy);
  650.     }
  651.     int comp = xl - yl;
  652.     if (comp == 0)
  653.       comp = docmp(x->s, tmp, yl);
  654.     if (comp == 0)
  655.       r = Icopy_zero(r);
  656.     else
  657.     {
  658.       if (xrsame)
  659.         r = Iresize(r, calc_len(xl, yl, 0));
  660.       else
  661.         r = Icalloc(r, calc_len(xl, yl, 0));
  662.       unsigned short* rs = r->s;
  663.       const unsigned short* as;
  664.       const unsigned short* bs;
  665.       const unsigned short* topa;
  666.       const unsigned short* topb;
  667.       if (comp > 0)
  668.       {
  669.         as =  (xrsame)? r->s : x->s;
  670.         topa = &(as[xl]);
  671.         bs =  tmp;
  672.         topb = &(bs[yl]);
  673.         r->sgn = xsgn;
  674.       }
  675.       else
  676.       {
  677.         bs =  (xrsame)? r->s : x->s;
  678.         topb = &(bs[xl]);
  679.         as =  tmp;
  680.         topa = &(as[yl]);
  681.         r->sgn = ysgn;
  682.       }
  683.       unsigned long hi = 1;
  684.       while (bs < topb)
  685.       {
  686.         hi += (unsigned long)(*as++) + I_MAXNUM - (unsigned long)(*bs++);
  687.         *rs++ = extract(hi);
  688.         hi = down(hi);
  689.       }
  690.       while (hi == 0 && as < topa)
  691.       {
  692.         hi = (unsigned long)(*as++) + I_MAXNUM;
  693.         *rs++ = extract(hi);
  694.         hi = down(hi);
  695.       }
  696.       if (rs != as)
  697.         while (as < topa)
  698.           *rs++ = *as++;
  699.     }
  700.   }
  701.   Icheck(r);
  702.   return r;
  703. }
  704.  
  705.  
  706. IntRep* multiply(const IntRep* x, const IntRep* y, IntRep* r)
  707. {
  708.   nonnil(x);
  709.   nonnil(y);
  710.   int xl = x->len;
  711.   int yl = y->len;
  712.   int rl = xl + yl;
  713.   int rsgn = x->sgn == y->sgn;
  714.   int xrsame = x == r;
  715.   int yrsame = y == r;
  716.   int xysame = x == y;
  717.   
  718.   if (xl == 0 || yl == 0)
  719.     r = Icopy_zero(r);
  720.   else if (xl == 1 && x->s[0] == 1)
  721.     r = Icopy(r, y);
  722.   else if (yl == 1 && y->s[0] == 1)
  723.     r = Icopy(r, x);
  724.   else if (!(xysame && xrsame))
  725.   {
  726.     if (xrsame || yrsame)
  727.       r = Iresize(r, rl);
  728.     else
  729.       r = Icalloc(r, rl);
  730.     unsigned short* rs = r->s;
  731.     unsigned short* topr = &(rs[rl]);
  732.  
  733.     // use best inner/outer loop params given constraints
  734.     unsigned short* currentr;
  735.     const unsigned short* bota;
  736.     const unsigned short* as;
  737.     const unsigned short* botb;
  738.     const unsigned short* topb;
  739.     if (xrsame)                 
  740.     { 
  741.       currentr = &(rs[xl-1]);
  742.       bota = rs;
  743.       as = currentr;
  744.       botb = y->s;
  745.       topb = &(botb[yl]);
  746.     }
  747.     else if (yrsame)
  748.     {
  749.       currentr = &(rs[yl-1]);
  750.       bota = rs;
  751.       as = currentr;
  752.       botb = x->s;
  753.       topb = &(botb[xl]);
  754.     }
  755.     else if (xl <= yl)
  756.     {
  757.       currentr = &(rs[xl-1]);
  758.       bota = x->s;
  759.       as = &(bota[xl-1]);
  760.       botb = y->s;
  761.       topb = &(botb[yl]);
  762.     }
  763.     else
  764.     {
  765.       currentr = &(rs[yl-1]);
  766.       bota = y->s;
  767.       as = &(bota[yl-1]);
  768.       botb = x->s;
  769.       topb = &(botb[xl]);
  770.     }
  771.  
  772.     while (as >= bota)
  773.     {
  774.       unsigned long ai = (unsigned long)(*as--);
  775.       unsigned short* rs = currentr--;
  776.       *rs = 0;
  777.       if (ai != 0)
  778.       {
  779.         unsigned long sum = 0;
  780.         const unsigned short* bs = botb;
  781.         while (bs < topb)
  782.         {
  783.           sum += ai * (unsigned long)(*bs++) + (unsigned long)(*rs);
  784.           *rs++ = extract(sum);
  785.           sum = down(sum);
  786.         }
  787.         while (sum != 0 && rs < topr)
  788.         {
  789.           sum += (unsigned long)(*rs);
  790.           *rs++ = extract(sum);
  791.           sum = down(sum);
  792.         }
  793.       }
  794.     }
  795.   }
  796.   else                          // x, y, and r same; compute over diagonals
  797.   {
  798.     r = Iresize(r, rl);
  799.     unsigned short* botr = r->s;
  800.     unsigned short* topr = &(botr[rl]);
  801.     unsigned short* rs =   &(botr[rl - 2]);
  802.  
  803.     const unsigned short* bota = (xrsame)? botr : x->s;
  804.     const unsigned short* loa =  &(bota[xl - 1]);
  805.     const unsigned short* hia =  loa;
  806.  
  807.     for (; rs >= botr; --rs)
  808.     {
  809.       const unsigned short* h = hia;
  810.       const unsigned short* l = loa;
  811.       unsigned long prod = (unsigned long)(*h) * (unsigned long)(*l);
  812.       *rs = 0;
  813.  
  814.       for(;;)
  815.       {
  816.         unsigned short* rt = rs;
  817.         unsigned long sum = prod + (unsigned long)(*rt);
  818.         *rt++ = extract(sum);
  819.         sum = down(sum);
  820.         while (sum != 0 && rt < topr)
  821.         {
  822.           sum += (unsigned long)(*rt);
  823.           *rt++ = extract(sum);
  824.           sum = down(sum);
  825.         }
  826.         if (h > l)
  827.         {
  828.           rt = rs;
  829.           sum = prod + (unsigned long)(*rt);
  830.           *rt++ = extract(sum);
  831.           sum = down(sum);
  832.           while (sum != 0 && rt < topr)
  833.           {
  834.             sum += (unsigned long)(*rt);
  835.             *rt++ = extract(sum);
  836.             sum = down(sum);
  837.           }
  838.           if (--h >= ++l)
  839.             prod = (unsigned long)(*h) * (unsigned long)(*l);
  840.           else
  841.             break;
  842.         }
  843.         else
  844.           break;
  845.       }
  846.       if (loa > bota)
  847.         --loa;
  848.       else
  849.         --hia;
  850.     }
  851.   }
  852.   r->sgn = rsgn;
  853.   Icheck(r);
  854.   return r;
  855. }
  856.  
  857.  
  858. IntRep* multiply(const IntRep* x, long y, IntRep* r)
  859. {
  860.   nonnil(x);
  861.   int xl = x->len;
  862.     
  863.   if (xl == 0 || y == 0)
  864.     r = Icopy_zero(r);
  865.   else if (y == 1)
  866.     r = Icopy(r, x);
  867.   else
  868.   {
  869.     int ysgn = y >= 0;
  870.     int rsgn = x->sgn == ysgn;
  871.     unsigned long uy = (ysgn)? y : -y;
  872.     unsigned short tmp[SHORT_PER_LONG];
  873.     int yl = 0;
  874.     while (uy != 0)
  875.     {
  876.       tmp[yl++] = extract(uy);
  877.       uy = down(uy);
  878.     }
  879.  
  880.     int rl = xl + yl;
  881.     int xrsame = x == r;
  882.     if (xrsame)
  883.       r = Iresize(r, rl);
  884.     else
  885.       r = Icalloc(r, rl);
  886.  
  887.     unsigned short* rs = r->s;
  888.     unsigned short* topr = &(rs[rl]);
  889.     unsigned short* currentr;
  890.     const unsigned short* bota;
  891.     const unsigned short* as;
  892.     const unsigned short* botb;
  893.     const unsigned short* topb;
  894.  
  895.     if (xrsame)
  896.     { 
  897.       currentr = &(rs[xl-1]);
  898.       bota = rs;
  899.       as = currentr;
  900.       botb = tmp;
  901.       topb = &(botb[yl]);
  902.     }
  903.     else if (xl <= yl)
  904.     {
  905.       currentr = &(rs[xl-1]);
  906.       bota = x->s;
  907.       as = &(bota[xl-1]);
  908.       botb = tmp;
  909.       topb = &(botb[yl]);
  910.     }
  911.     else
  912.     {
  913.       currentr = &(rs[yl-1]);
  914.       bota = tmp;
  915.       as = &(bota[yl-1]);
  916.       botb = x->s;
  917.       topb = &(botb[xl]);
  918.     }
  919.  
  920.     while (as >= bota)
  921.     {
  922.       unsigned long ai = (unsigned long)(*as--);
  923.       unsigned short* rs = currentr--;
  924.       *rs = 0;
  925.       if (ai != 0)
  926.       {
  927.         unsigned long sum = 0;
  928.         const unsigned short* bs = botb;
  929.         while (bs < topb)
  930.         {
  931.           sum += ai * (unsigned long)(*bs++) + (unsigned long)(*rs);
  932.           *rs++ = extract(sum);
  933.           sum = down(sum);
  934.         }
  935.         while (sum != 0 && rs < topr)
  936.         {
  937.           sum += (unsigned long)(*rs);
  938.           *rs++ = extract(sum);
  939.           sum = down(sum);
  940.         }
  941.       }
  942.     }
  943.     r->sgn = rsgn;
  944.   }
  945.   Icheck(r);
  946.   return r;
  947. }
  948.  
  949.  
  950. // main division routine
  951.  
  952. static void do_divide(unsigned short* rs,
  953.                       const unsigned short* ys, int yl,
  954.                       unsigned short* qs, int ql)
  955. {
  956.   const unsigned short* topy = &(ys[yl]);
  957.   unsigned short d1 = ys[yl - 1];
  958.   unsigned short d2 = ys[yl - 2];
  959.  
  960.   int l = ql - 1;
  961.   int i = l + yl;
  962.   
  963.   for (; l >= 0; --l, --i)
  964.   {
  965.     unsigned short qhat;       // guess q
  966.     if (d1 == rs[i])
  967.       qhat = I_MAXNUM;
  968.     else
  969.     {
  970.       unsigned long lr = up((unsigned long)rs[i]) | rs[i-1];
  971.       qhat = lr / d1;
  972.     }
  973.  
  974.     for(;;)     // adjust q, use docmp to avoid overflow problems
  975.     {
  976.       unsigned short ts[3];
  977.       unsigned long prod = (unsigned long)d2 * (unsigned long)qhat;
  978.       ts[0] = extract(prod);
  979.       prod = down(prod) + (unsigned long)d1 * (unsigned long)qhat;
  980.       ts[1] = extract(prod);
  981.       ts[2] = extract(down(prod));
  982.       if (docmp(ts, &(rs[i-2]), 3) > 0)
  983.         --qhat;
  984.       else
  985.         break;
  986.     };
  987.     
  988.     // multiply & subtract
  989.     
  990.     const unsigned short* yt = ys;
  991.     unsigned short* rt = &(rs[l]);
  992.     unsigned long prod = 0;
  993.     unsigned long hi = 1;
  994.     while (yt < topy)
  995.     {
  996.       prod = (unsigned long)qhat * (unsigned long)(*yt++) + down(prod);
  997.       hi += (unsigned long)(*rt) + I_MAXNUM - (unsigned long)(extract(prod));
  998.       *rt++ = extract(hi);
  999.       hi = down(hi);
  1000.     }
  1001.     hi += (unsigned long)(*rt) + I_MAXNUM - (unsigned long)(down(prod));
  1002.     *rt = extract(hi);
  1003.     hi = down(hi);
  1004.     
  1005.     // off-by-one, add back
  1006.     
  1007.     if (hi == 0)
  1008.     {
  1009.       --qhat;
  1010.       yt = ys;
  1011.       rt = &(rs[l]);
  1012.       hi = 0;
  1013.       while (yt < topy)
  1014.       {
  1015.         hi = (unsigned long)(*rt) + (unsigned long)(*yt++) + down(hi);
  1016.         *rt++ = extract(hi);
  1017.       }
  1018.       *rt = 0;
  1019.     }
  1020.     if (qs != 0)
  1021.       qs[l] = qhat;
  1022.   }
  1023. }
  1024.  
  1025. // divide by single digit, return remainder
  1026. // if q != 0, then keep the result in q, else just compute rem
  1027.  
  1028. static int unscale(const unsigned short* x, int xl, unsigned short y,
  1029.                    unsigned short* q)
  1030. {
  1031.   if (xl == 0 || y == 1)
  1032.     return 0;
  1033.   else if (q != 0)
  1034.   {
  1035.     unsigned short* botq = q;
  1036.     unsigned short* qs = &(botq[xl - 1]);
  1037.     const unsigned short* xs = &(x[xl - 1]);
  1038.     unsigned long rem = 0;
  1039.     while (qs >= botq)
  1040.     {
  1041.       rem = up(rem) | *xs--;
  1042.       unsigned long u = rem / y;
  1043.       *qs-- = extract(u);
  1044.       rem -= u * y;
  1045.     }
  1046.     int r = extract(rem);
  1047.     return r;
  1048.   }
  1049.   else                          // same loop, a bit faster if just need rem
  1050.   {
  1051.     const unsigned short* botx = x;
  1052.     const unsigned short* xs = &(botx[xl - 1]);
  1053.     unsigned long rem = 0;
  1054.     while (xs >= botx)
  1055.     {
  1056.       rem = up(rem) | *xs--;
  1057.       unsigned long u = rem / y;
  1058.       rem -= u * y;
  1059.     }
  1060.     int r = extract(rem);
  1061.     return r;
  1062.   }
  1063. }
  1064.  
  1065.  
  1066. IntRep* div(const IntRep* x, const IntRep* y, IntRep* q)
  1067. {
  1068.   nonnil(x);
  1069.   nonnil(y);
  1070.   int xl = x->len;
  1071.   int yl = y->len;
  1072.   if (yl == 0) (*lib_error_handler)("Integer", "attempted division by zero");
  1073.  
  1074.   int comp = ucompare(x, y);
  1075.   int xsgn = x->sgn;
  1076.   int ysgn = y->sgn;
  1077.  
  1078.   int samesign = xsgn == ysgn;
  1079.  
  1080.   if (comp < 0)
  1081.     q = Icopy_zero(q);
  1082.   else if (comp == 0)
  1083.     q = Icopy_one(q, samesign);
  1084.   else if (yl == 1)
  1085.   {
  1086.     q = Icopy(q, x);
  1087.     unscale(q->s, q->len, y->s[0], q->s);
  1088.   }
  1089.   else
  1090.   {
  1091.     IntRep* yy = 0;
  1092.     IntRep* r  = 0;
  1093.     unsigned short prescale = (I_RADIX / (1 + y->s[yl - 1]));
  1094.     if (prescale != 1 || y == q)
  1095.     {
  1096.       yy = multiply(y, ((long)prescale & I_MAXNUM), yy);
  1097.       r = multiply(x, ((long)prescale & I_MAXNUM), r);
  1098.     }
  1099.     else
  1100.     {
  1101.       yy = (IntRep*)y;
  1102.       r = Icalloc(r, xl + 1);
  1103.       scpy(x->s, r->s, xl);
  1104.     }
  1105.  
  1106.     int ql = xl - yl + 1;
  1107.       
  1108.     q = Icalloc(q, ql);
  1109.     do_divide(r->s, yy->s, yl, q->s, ql);
  1110.  
  1111.     if (yy != y && !STATIC_IntRep(yy)) delete yy;
  1112.     if (!STATIC_IntRep(r)) delete r;
  1113.   }
  1114.   q->sgn = samesign;
  1115.   Icheck(q);
  1116.   return q;
  1117. }
  1118.  
  1119. IntRep* div(const IntRep* x, long y, IntRep* q)
  1120. {
  1121.   nonnil(x);
  1122.   int xl = x->len;
  1123.   if (y == 0) (*lib_error_handler)("Integer", "attempted division by zero");
  1124.  
  1125.   unsigned short ys[SHORT_PER_LONG];
  1126.   unsigned long u;
  1127.   int ysgn = y >= 0;
  1128.   if (ysgn)
  1129.     u = y;
  1130.   else
  1131.     u = -y;
  1132.   int yl = 0;
  1133.   while (u != 0)
  1134.   {
  1135.     ys[yl++] = extract(u);
  1136.     u = down(u);
  1137.   }
  1138.  
  1139.   int comp = xl - yl;
  1140.   if (comp == 0) comp = docmp(x->s, ys, xl);
  1141.  
  1142.   int xsgn = x->sgn;
  1143.   int samesign = xsgn == ysgn;
  1144.  
  1145.   if (comp < 0)
  1146.     q = Icopy_zero(q);
  1147.   else if (comp == 0)
  1148.   {
  1149.     q = Icopy_one(q, samesign);
  1150.   }
  1151.   else if (yl == 1)
  1152.   {
  1153.     q = Icopy(q, x);
  1154.     unscale(q->s, q->len, ys[0], q->s);
  1155.   }
  1156.   else
  1157.   {
  1158.     IntRep* r  = 0;
  1159.     unsigned short prescale = (I_RADIX / (1 + ys[yl - 1]));
  1160.     if (prescale != 1)
  1161.     {
  1162.       unsigned long prod = (unsigned long)prescale * (unsigned long)ys[0];
  1163.       ys[0] = extract(prod);
  1164.       prod = down(prod) + (unsigned long)prescale * (unsigned long)ys[1];
  1165.       ys[1] = extract(prod);
  1166.       r = multiply(x, ((long)prescale & I_MAXNUM), r);
  1167.     }
  1168.     else
  1169.     {
  1170.       r = Icalloc(r, xl + 1);
  1171.       scpy(x->s, r->s, xl);
  1172.     }
  1173.  
  1174.     int ql = xl - yl + 1;
  1175.       
  1176.     q = Icalloc(q, ql);
  1177.     do_divide(r->s, ys, yl, q->s, ql);
  1178.  
  1179.     if (!STATIC_IntRep(r)) delete r;
  1180.   }
  1181.   q->sgn = samesign;
  1182.   Icheck(q);
  1183.   return q;
  1184. }
  1185.  
  1186.  
  1187. void divide(const Integer& Ix, long y, Integer& Iq, long& rem)
  1188. {
  1189.   const IntRep* x = Ix.rep;
  1190.   nonnil(x);
  1191.   IntRep* q = Iq.rep;
  1192.   int xl = x->len;
  1193.   if (y == 0) (*lib_error_handler)("Integer", "attempted division by zero");
  1194.  
  1195.   unsigned short ys[SHORT_PER_LONG];
  1196.   unsigned long u;
  1197.   int ysgn = y >= 0;
  1198.   if (ysgn)
  1199.     u = y;
  1200.   else
  1201.     u = -y;
  1202.   int yl = 0;
  1203.   while (u != 0)
  1204.   {
  1205.     ys[yl++] = extract(u);
  1206.     u = down(u);
  1207.   }
  1208.  
  1209.   int comp = xl - yl;
  1210.   if (comp == 0) comp = docmp(x->s, ys, xl);
  1211.  
  1212.   int xsgn = x->sgn;
  1213.   int samesign = xsgn == ysgn;
  1214.  
  1215.   if (comp < 0)
  1216.   {
  1217.     rem = Itolong(x);
  1218.     q = Icopy_zero(q);
  1219.   }
  1220.   else if (comp == 0)
  1221.   {
  1222.     q = Icopy_one(q, samesign);
  1223.     rem = 0;
  1224.   }
  1225.   else if (yl == 1)
  1226.   {
  1227.     q = Icopy(q, x);
  1228.     rem = unscale(q->s, q->len, ys[0], q->s);
  1229.   }
  1230.   else
  1231.   {
  1232.     IntRep* r  = 0;
  1233.     unsigned short prescale = (I_RADIX / (1 + ys[yl - 1]));
  1234.     if (prescale != 1)
  1235.     {
  1236.       unsigned long prod = (unsigned long)prescale * (unsigned long)ys[0];
  1237.       ys[0] = extract(prod);
  1238.       prod = down(prod) + (unsigned long)prescale * (unsigned long)ys[1];
  1239.       ys[1] = extract(prod);
  1240.       r = multiply(x, ((long)prescale & I_MAXNUM), r);
  1241.     }
  1242.     else
  1243.     {
  1244.       r = Icalloc(r, xl + 1);
  1245.       scpy(x->s, r->s, xl);
  1246.     }
  1247.  
  1248.     int ql = xl - yl + 1;
  1249.       
  1250.     q = Icalloc(q, ql);
  1251.     
  1252.     do_divide(r->s, ys, yl, q->s, ql);
  1253.  
  1254.     if (prescale != 1)
  1255.     {
  1256.       Icheck(r);
  1257.       unscale(r->s, r->len, prescale, r->s);
  1258.     }
  1259.     Icheck(r);
  1260.     rem = Itolong(r);
  1261.     if (!STATIC_IntRep(r)) delete r;
  1262.   }
  1263.   rem = abs(rem);
  1264.   if (xsgn == I_NEGATIVE) rem = -rem;
  1265.   q->sgn = samesign;
  1266.   Icheck(q);
  1267.   Iq.rep = q;
  1268. }
  1269.  
  1270.  
  1271. void divide(const Integer& Ix, const Integer& Iy, Integer& Iq, Integer& Ir)
  1272. {
  1273.   const IntRep* x = Ix.rep;
  1274.   nonnil(x);
  1275.   const IntRep* y = Iy.rep;
  1276.   nonnil(y);
  1277.   IntRep* q = Iq.rep;
  1278.   IntRep* r = Ir.rep;
  1279.  
  1280.   int xl = x->len;
  1281.   int yl = y->len;
  1282.   if (yl == 0)
  1283.     (*lib_error_handler)("Integer", "attempted division by zero");
  1284.  
  1285.   int comp = ucompare(x, y);
  1286.   int xsgn = x->sgn;
  1287.   int ysgn = y->sgn;
  1288.  
  1289.   int samesign = xsgn == ysgn;
  1290.  
  1291.   if (comp < 0)
  1292.   {
  1293.     q = Icopy_zero(q);
  1294.     r = Icopy(r, x);
  1295.   }
  1296.   else if (comp == 0)
  1297.   {
  1298.     q = Icopy_one(q, samesign);
  1299.     r = Icopy_zero(r);
  1300.   }
  1301.   else if (yl == 1)
  1302.   {
  1303.     q = Icopy(q, x);
  1304.     int rem =  unscale(q->s, q->len, y->s[0], q->s);
  1305.     r = Icopy_long(r, rem);
  1306.     if (rem != 0)
  1307.       r->sgn = xsgn;
  1308.   }
  1309.   else
  1310.   {
  1311.     IntRep* yy = 0;
  1312.     unsigned short prescale = (I_RADIX / (1 + y->s[yl - 1]));
  1313.     if (prescale != 1 || y == q || y == r)
  1314.     {
  1315.       yy = multiply(y, ((long)prescale & I_MAXNUM), yy);
  1316.       r = multiply(x, ((long)prescale & I_MAXNUM), r);
  1317.     }
  1318.     else
  1319.     {
  1320.       yy = (IntRep*)y;
  1321.       r = Icalloc(r, xl + 1);
  1322.       scpy(x->s, r->s, xl);
  1323.     }
  1324.  
  1325.     int ql = xl - yl + 1;
  1326.       
  1327.     q = Icalloc(q, ql);
  1328.     do_divide(r->s, yy->s, yl, q->s, ql);
  1329.  
  1330.     if (yy != y && !STATIC_IntRep(yy)) delete yy;
  1331.     if (prescale != 1)
  1332.     {
  1333.       Icheck(r);
  1334.       unscale(r->s, r->len, prescale, r->s);
  1335.     }
  1336.   }
  1337.   q->sgn = samesign;
  1338.   Icheck(q);
  1339.   Iq.rep = q;
  1340.   Icheck(r);
  1341.   Ir.rep = r;
  1342. }
  1343.  
  1344. IntRep* mod(const IntRep* x, const IntRep* y, IntRep* r)
  1345. {
  1346.   nonnil(x);
  1347.   nonnil(y);
  1348.   int xl = x->len;
  1349.   int yl = y->len;
  1350.   if (yl == 0) (*lib_error_handler)("Integer", "attempted division by zero");
  1351.  
  1352.   int comp = ucompare(x, y);
  1353.   int xsgn = x->sgn;
  1354.  
  1355.   if (comp < 0)
  1356.     r = Icopy(r, x);
  1357.   else if (comp == 0)
  1358.     r = Icopy_zero(r);
  1359.   else if (yl == 1)
  1360.   {
  1361.     int rem = unscale(x->s, xl, y->s[0], 0);
  1362.     r = Icopy_long(r, rem);
  1363.     if (rem != 0)
  1364.       r->sgn = xsgn;
  1365.   }
  1366.   else
  1367.   {
  1368.     IntRep* yy = 0;
  1369.     unsigned short prescale = (I_RADIX / (1 + y->s[yl - 1]));
  1370.     if (prescale != 1 || y == r)
  1371.     {
  1372.       yy = multiply(y, ((long)prescale & I_MAXNUM), yy);
  1373.       r = multiply(x, ((long)prescale & I_MAXNUM), r);
  1374.     }
  1375.     else
  1376.     {
  1377.       yy = (IntRep*)y;
  1378.       r = Icalloc(r, xl + 1);
  1379.       scpy(x->s, r->s, xl);
  1380.     }
  1381.       
  1382.     do_divide(r->s, yy->s, yl, 0, xl - yl + 1);
  1383.  
  1384.     if (yy != y && !STATIC_IntRep(yy)) delete yy;
  1385.  
  1386.     if (prescale != 1)
  1387.     {
  1388.       Icheck(r);
  1389.       unscale(r->s, r->len, prescale, r->s);
  1390.     }
  1391.   }
  1392.   Icheck(r);
  1393.   return r;
  1394. }
  1395.  
  1396. IntRep* mod(const IntRep* x, long y, IntRep* r)
  1397. {
  1398.   nonnil(x);
  1399.   int xl = x->len;
  1400.   if (y == 0) (*lib_error_handler)("Integer", "attempted division by zero");
  1401.  
  1402.   unsigned short ys[SHORT_PER_LONG];
  1403.   unsigned long u;
  1404.   int ysgn = y >= 0;
  1405.   if (ysgn)
  1406.     u = y;
  1407.   else
  1408.     u = -y;
  1409.   int yl = 0;
  1410.   while (u != 0)
  1411.   {
  1412.     ys[yl++] = extract(u);
  1413.     u = down(u);
  1414.   }
  1415.  
  1416.   int comp = xl - yl;
  1417.   if (comp == 0) comp = docmp(x->s, ys, xl);
  1418.  
  1419.   int xsgn = x->sgn;
  1420.  
  1421.   if (comp < 0)
  1422.     r = Icopy(r, x);
  1423.   else if (comp == 0)
  1424.     r = Icopy_zero(r);
  1425.   else if (yl == 1)
  1426.   {
  1427.     int rem = unscale(x->s, xl, ys[0], 0);
  1428.     r = Icopy_long(r, rem);
  1429.     if (rem != 0)
  1430.       r->sgn = xsgn;
  1431.   }
  1432.   else
  1433.   {
  1434.     unsigned short prescale = (I_RADIX / (1 + ys[yl - 1]));
  1435.     if (prescale != 1)
  1436.     {
  1437.       unsigned long prod = (unsigned long)prescale * (unsigned long)ys[0];
  1438.       ys[0] = extract(prod);
  1439.       prod = down(prod) + (unsigned long)prescale * (unsigned long)ys[1];
  1440.       ys[1] = extract(prod);
  1441.       r = multiply(x, ((long)prescale & I_MAXNUM), r);
  1442.     }
  1443.     else
  1444.     {
  1445.       r = Icalloc(r, xl + 1);
  1446.       scpy(x->s, r->s, xl);
  1447.     }
  1448.       
  1449.     do_divide(r->s, ys, yl, 0, xl - yl + 1);
  1450.  
  1451.     if (prescale != 1)
  1452.     {
  1453.       Icheck(r);
  1454.       unscale(r->s, r->len, prescale, r->s);
  1455.     }
  1456.   }
  1457.   Icheck(r);
  1458.   return r;
  1459. }
  1460.  
  1461. IntRep* lshift(const IntRep* x, long y, IntRep* r)
  1462. {
  1463.   nonnil(x);
  1464.   int xl = x->len;
  1465.   if (xl == 0 || y == 0)
  1466.   {
  1467.     r = Icopy(r, x);
  1468.     return r;
  1469.   }
  1470.  
  1471.   int xrsame = x == r;
  1472.   int rsgn = x->sgn;
  1473.  
  1474.   long ay = (y < 0)? -y : y;
  1475.   int bw = ay / I_SHIFT;
  1476.   int sw = ay % I_SHIFT;
  1477.  
  1478.   if (y > 0)
  1479.   {
  1480.     int rl = bw + xl + 1;
  1481.     if (xrsame)
  1482.       r = Iresize(r, rl);
  1483.     else
  1484.       r = Icalloc(r, rl);
  1485.  
  1486.     unsigned short* botr = r->s;
  1487.     unsigned short* rs = &(botr[rl - 1]);
  1488.     const unsigned short* botx = (xrsame)? botr : x->s;
  1489.     const unsigned short* xs = &(botx[xl - 1]);
  1490.     unsigned long a = 0;
  1491.     while (xs >= botx)
  1492.     {
  1493.       a = up(a) | ((unsigned long)(*xs--) << sw);
  1494.       *rs-- = extract(down(a));
  1495.     }
  1496.     *rs-- = extract(a);
  1497.     while (rs >= botr)
  1498.       *rs-- = 0;
  1499.   }
  1500.   else
  1501.   {
  1502.     int rl = xl - bw;
  1503.     if (rl < 0)
  1504.       r = Icopy_zero(r);
  1505.     else
  1506.     {
  1507.       if (xrsame)
  1508.         r = Iresize(r, rl);
  1509.       else
  1510.         r = Icalloc(r, rl);
  1511.       int rw = I_SHIFT - sw;
  1512.       unsigned short* rs = r->s;
  1513.       unsigned short* topr = &(rs[rl]);
  1514.       const unsigned short* botx = (xrsame)? rs : x->s;
  1515.       const unsigned short* xs =  &(botx[bw]);
  1516.       const unsigned short* topx = &(botx[xl]);
  1517.       unsigned long a = (unsigned long)(*xs++) >> sw;
  1518.       while (xs < topx)
  1519.       {
  1520.         a |= (unsigned long)(*xs++) << rw;
  1521.         *rs++ = extract(a);
  1522.         a = down(a);
  1523.       }
  1524.       *rs++ = extract(a);
  1525.       if (xrsame) topr = (unsigned short*)topx;
  1526.       while (rs < topr)
  1527.         *rs++ = 0;
  1528.     }
  1529.   }
  1530.   r->sgn = rsgn;
  1531.   Icheck(r);
  1532.   return r;
  1533. }
  1534.  
  1535. IntRep* lshift(const IntRep* x, const IntRep* yy, int negatey, IntRep* r)
  1536. {
  1537.   long y = Itolong(yy);
  1538.   if (negatey)
  1539.     y = -y;
  1540.  
  1541.   return lshift(x, y, r);
  1542. }
  1543.  
  1544. IntRep* bitop(const IntRep* x, const IntRep* y, IntRep* r, char op)
  1545. {
  1546.   nonnil(x);
  1547.   nonnil(y);
  1548.   int xl = x->len;
  1549.   int yl = y->len;
  1550.   int xsgn = x->sgn;
  1551.   int xrsame = x == r;
  1552.   int yrsame = y == r;
  1553.   if (xrsame || yrsame)
  1554.     r = Iresize(r, calc_len(xl, yl, 0));
  1555.   else
  1556.     r = Icalloc(r, calc_len(xl, yl, 0));
  1557.   r->sgn = xsgn;
  1558.   unsigned short* rs = r->s;
  1559.   unsigned short* topr = &(rs[r->len]);
  1560.   const unsigned short* as;
  1561.   const unsigned short* bs;
  1562.   const unsigned short* topb;
  1563.   if (xl >= yl)
  1564.   {
  1565.     as = (xrsame)? rs : x->s;
  1566.     bs = (yrsame)? rs : y->s;
  1567.     topb = &(bs[yl]);
  1568.   }
  1569.   else
  1570.   {
  1571.     bs = (xrsame)? rs : x->s;
  1572.     topb = &(bs[xl]);
  1573.     as = (yrsame)? rs : y->s;
  1574.   }
  1575.  
  1576.   switch (op)
  1577.   {
  1578.   case '&':
  1579.     while (bs < topb) *rs++ = *as++ & *bs++;
  1580.     while (rs < topr) *rs++ = 0;
  1581.     break;
  1582.   case '|':
  1583.     while (bs < topb) *rs++ = *as++ | *bs++;
  1584.     while (rs < topr) *rs++ = *as++;
  1585.     break;
  1586.   case '^':
  1587.     while (bs < topb) *rs++ = *as++ ^ *bs++;
  1588.     while (rs < topr) *rs++ = *as++;
  1589.     break;
  1590.   }
  1591.   Icheck(r);
  1592.   return r;
  1593. }
  1594.  
  1595. IntRep* bitop(const IntRep* x, long y, IntRep* r, char op)
  1596. {
  1597.   nonnil(x);
  1598.   unsigned short tmp[SHORT_PER_LONG];
  1599.   unsigned long u;
  1600.   int newsgn;
  1601.   if (newsgn = (y >= 0))
  1602.     u = y;
  1603.   else
  1604.     u = -y;
  1605.   
  1606.   int l = 0;
  1607.   while (u != 0)
  1608.   {
  1609.     tmp[l++] = extract(u);
  1610.     u = down(u);
  1611.   }
  1612.  
  1613.   int xl = x->len;
  1614.   int yl = l;
  1615.   int xsgn = x->sgn;
  1616.   int xrsame = x == r;
  1617.   if (xrsame)
  1618.     r = Iresize(r, calc_len(xl, yl, 0));
  1619.   else
  1620.     r = Icalloc(r, calc_len(xl, yl, 0));
  1621.   r->sgn = xsgn;
  1622.   unsigned short* rs = r->s;
  1623.   unsigned short* topr = &(rs[r->len]);
  1624.   const unsigned short* as;
  1625.   const unsigned short* bs;
  1626.   const unsigned short* topb;
  1627.   if (xl >= yl)
  1628.   {
  1629.     as = (xrsame)? rs : x->s;
  1630.     bs = tmp;
  1631.     topb = &(bs[yl]);
  1632.   }
  1633.   else
  1634.   {
  1635.     bs = (xrsame)? rs : x->s;
  1636.     topb = &(bs[xl]);
  1637.     as = tmp;
  1638.   }
  1639.  
  1640.   switch (op)
  1641.   {
  1642.   case '&':
  1643.     while (bs < topb) *rs++ = *as++ & *bs++;
  1644.     while (rs < topr) *rs++ = 0;
  1645.     break;
  1646.   case '|':
  1647.     while (bs < topb) *rs++ = *as++ | *bs++;
  1648.     while (rs < topr) *rs++ = *as++;
  1649.     break;
  1650.   case '^':
  1651.     while (bs < topb) *rs++ = *as++ ^ *bs++;
  1652.     while (rs < topr) *rs++ = *as++;
  1653.     break;
  1654.   }
  1655.   Icheck(r);
  1656.   return r;
  1657. }
  1658.  
  1659.  
  1660.  
  1661. IntRep*  compl(const IntRep* src, IntRep* r)
  1662. {
  1663.   nonnil(src);
  1664.   r = Icopy(r, src);
  1665.   unsigned short* s = r->s;
  1666.   unsigned short* top = &(s[r->len - 1]);
  1667.   while (s < top)
  1668.   {
  1669.     unsigned short cmp = ~(*s);
  1670.     *s++ = cmp;
  1671.   }
  1672.   unsigned short a = *s;
  1673.   unsigned short b = 0;
  1674.   while (a != 0)
  1675.   {
  1676.     b <<= 1;
  1677.     if (!(a & 1)) b |= 1;
  1678.     a >>= 1;
  1679.   }
  1680.   *s = b;
  1681.   Icheck(r);
  1682.   return r;
  1683. }
  1684.  
  1685. void (setbit)(Integer& x, long b)
  1686. {
  1687.   if (b >= 0)
  1688.   {
  1689.     int bw = (unsigned long)b / I_SHIFT;
  1690.     int sw = (unsigned long)b % I_SHIFT;
  1691.     int xl = x.rep ? x.rep->len : 0;
  1692.     if (xl <= bw)
  1693.       x.rep = Iresize(x.rep, calc_len(xl, bw+1, 0));
  1694.     x.rep->s[bw] |= (1 << sw);
  1695.     Icheck(x.rep);
  1696.   }
  1697. }
  1698.  
  1699. void clearbit(Integer& x, long b)
  1700. {
  1701.   if (b >= 0)
  1702.     {
  1703.       if (x.rep == 0)
  1704.     x.rep = &_ZeroRep;
  1705.       else
  1706.     {
  1707.       int bw = (unsigned long)b / I_SHIFT;
  1708.       int sw = (unsigned long)b % I_SHIFT;
  1709.       if (x.rep->len > bw)
  1710.         x.rep->s[bw] &= ~(1 << sw);
  1711.     }
  1712.     Icheck(x.rep);
  1713.   }
  1714. }
  1715.  
  1716. int testbit(const Integer& x, long b)
  1717. {
  1718.   if (x.rep != 0 && b >= 0)
  1719.   {
  1720.     int bw = (unsigned long)b / I_SHIFT;
  1721.     int sw = (unsigned long)b % I_SHIFT;
  1722.     return (bw < x.rep->len && (x.rep->s[bw] & (1 << sw)) != 0);
  1723.   }
  1724.   else
  1725.     return 0;
  1726. }
  1727.  
  1728. // A  version of knuth's algorithm B / ex. 4.5.3.34
  1729. // A better version that doesn't bother shifting all of `t' forthcoming
  1730.  
  1731. IntRep* gcd(const IntRep* x, const IntRep* y)
  1732. {
  1733.   nonnil(x);
  1734.   nonnil(y);
  1735.   int ul = x->len;
  1736.   int vl = y->len;
  1737.   
  1738.   if (vl == 0)
  1739.     return Ialloc(0, x->s, ul, I_POSITIVE, ul);
  1740.   else if (ul == 0)
  1741.     return Ialloc(0, y->s, vl, I_POSITIVE, vl);
  1742.  
  1743.   IntRep* u = Ialloc(0, x->s, ul, I_POSITIVE, ul);
  1744.   IntRep* v = Ialloc(0, y->s, vl, I_POSITIVE, vl);
  1745.  
  1746. // find shift so that both not even
  1747.  
  1748.   long k = 0;
  1749.   int l = (ul <= vl)? ul : vl;
  1750.   int cont = 1;
  1751.   for (int i = 0;  i < l && cont; ++i)
  1752.   {
  1753.     unsigned long a =  (i < ul)? u->s[i] : 0;
  1754.     unsigned long b =  (i < vl)? v->s[i] : 0;
  1755.     for (int j = 0; j < I_SHIFT; ++j)
  1756.     {
  1757.       if ((a | b) & 1)
  1758.       {
  1759.         cont = 0;
  1760.         break;
  1761.       }
  1762.       else
  1763.       {
  1764.         ++k;
  1765.         a >>= 1;
  1766.         b >>= 1;
  1767.       }
  1768.     }
  1769.   }
  1770.  
  1771.   if (k != 0)
  1772.   {
  1773.     u = lshift(u, -k, u);
  1774.     v = lshift(v, -k, v);
  1775.   }
  1776.  
  1777.   IntRep* t;
  1778.   if (u->s[0] & 01)
  1779.     t = Ialloc(0, v->s, v->len, !v->sgn, v->len);
  1780.   else
  1781.     t = Ialloc(0, u->s, u->len, u->sgn, u->len);
  1782.  
  1783.   while (t->len != 0)
  1784.   {
  1785.     long s = 0;                 // shift t until odd
  1786.     cont = 1;
  1787.     int tl = t->len;
  1788.     for (i = 0; i < tl && cont; ++i)
  1789.     {
  1790.       unsigned long a = t->s[i];
  1791.       for (int j = 0; j < I_SHIFT; ++j)
  1792.       {
  1793.         if (a & 1)
  1794.         {
  1795.           cont = 0;
  1796.           break;
  1797.         }
  1798.         else
  1799.         {
  1800.           ++s;
  1801.           a >>= 1;
  1802.         }
  1803.       }
  1804.     }
  1805.  
  1806.     if (s != 0) t = lshift(t, -s, t);
  1807.  
  1808.     if (t->sgn == I_POSITIVE)
  1809.     {
  1810.       u = Icopy(u, t);
  1811.       t = add(t, 0, v, 1, t);
  1812.     }
  1813.     else
  1814.     {
  1815.       v = Ialloc(v, t->s, t->len, !t->sgn, t->len);
  1816.       t = add(t, 0, u, 0, t);
  1817.     }
  1818.   }
  1819.   if (!STATIC_IntRep(t)) delete t;
  1820.   if (!STATIC_IntRep(v)) delete v;
  1821.   if (k != 0) u = lshift(u, k, u);
  1822.   return u;
  1823. }
  1824.  
  1825.  
  1826.  
  1827. long lg(const IntRep* x)
  1828. {
  1829.   nonnil(x);
  1830.   int xl = x->len;
  1831.   if (xl == 0)
  1832.     return 0;
  1833.  
  1834.   long l = (xl - 1) * I_SHIFT - 1;
  1835.   unsigned short a = x->s[xl-1];
  1836.  
  1837.   while (a != 0)
  1838.   {
  1839.     a = a >> 1;
  1840.     ++l;
  1841.   }
  1842.   return l;
  1843. }
  1844.   
  1845. IntRep* power(const IntRep* x, long y, IntRep* r)
  1846. {
  1847.   nonnil(x);
  1848.   int sgn;
  1849.   if (x->sgn == I_POSITIVE || (!(y & 1)))
  1850.     sgn = I_POSITIVE;
  1851.   else
  1852.     sgn = I_NEGATIVE;
  1853.  
  1854.   int xl = x->len;
  1855.  
  1856.   if (y == 0 || (xl == 1 && x->s[0] == 1))
  1857.     r = Icopy_one(r, sgn);
  1858.   else if (xl == 0 || y < 0)
  1859.     r = Icopy_zero(r);
  1860.   else if (y == 1 || y == -1)
  1861.     r = Icopy(r, x);
  1862.   else
  1863.   {
  1864.     int maxsize = ((lg(x) + 1) * y) / I_SHIFT + 2;     // pre-allocate space
  1865.     IntRep* b = Ialloc(0, x->s, xl, I_POSITIVE, maxsize);
  1866.     b->len = xl;
  1867.     r = Icalloc(r, maxsize);
  1868.     r = Icopy_one(r, I_POSITIVE);
  1869.     for(;;)
  1870.     {
  1871.       if (y & 1)
  1872.         r = multiply(r, b, r);
  1873.       if ((y >>= 1) == 0)
  1874.         break;
  1875.       else
  1876.         b = multiply(b, b, b);
  1877.     }
  1878.     if (!STATIC_IntRep(b)) delete b;
  1879.   }
  1880.   r->sgn = sgn;
  1881.   Icheck(r);
  1882.   return r;
  1883. }
  1884.  
  1885. IntRep* abs(const IntRep* src, IntRep* dest)
  1886. {
  1887.   nonnil(src);
  1888.   if (src != dest)
  1889.     dest = Icopy(dest, src);
  1890.   dest->sgn = I_POSITIVE;
  1891.   return dest;
  1892. }
  1893.  
  1894. IntRep* negate(const IntRep* src, IntRep* dest)
  1895. {
  1896.   nonnil(src);
  1897.   if (src != dest)
  1898.     dest = Icopy(dest, src);
  1899.   if (dest->len != 0) 
  1900.     dest->sgn = !dest->sgn;
  1901.   return dest;
  1902. }
  1903.  
  1904. #if defined(__GNUG__) && !defined(_G_NO_NRV)
  1905.  
  1906. Integer sqrt(const Integer& x) return r(x)
  1907. {
  1908.   int s = sign(x);
  1909.   if (s < 0) x.error("Attempted square root of negative Integer");
  1910.   if (s != 0)
  1911.   {
  1912.     r >>= (lg(x) / 2); // get close
  1913.     Integer q;
  1914.     div(x, r, q);
  1915.     while (q < r)
  1916.     {
  1917.       r += q;
  1918.       r >>= 1;
  1919.       div(x, r, q);
  1920.     }
  1921.   }
  1922.   return;
  1923. }
  1924.  
  1925. Integer lcm(const Integer& x, const Integer& y) return r
  1926. {
  1927.   if (!x.initialized() || !y.initialized())
  1928.     x.error("operation on uninitialized Integer");
  1929.   Integer g;
  1930.   if (sign(x) == 0 || sign(y) == 0)
  1931.     g = 1;
  1932.   else 
  1933.     g = gcd(x, y);
  1934.   div(x, g, r);
  1935.   mul(r, y, r);
  1936. }
  1937.  
  1938. #else 
  1939. Integer sqrt(const Integer& x) 
  1940. {
  1941.   Integer r(x);
  1942.   int s = sign(x);
  1943.   if (s < 0) x.error("Attempted square root of negative Integer");
  1944.   if (s != 0)
  1945.   {
  1946.     r >>= (lg(x) / 2); // get close
  1947.     Integer q;
  1948.     div(x, r, q);
  1949.     while (q < r)
  1950.     {
  1951.       r += q;
  1952.       r >>= 1;
  1953.       div(x, r, q);
  1954.     }
  1955.   }
  1956.   return r;
  1957. }
  1958.  
  1959. Integer lcm(const Integer& x, const Integer& y) 
  1960. {
  1961.   Integer r;
  1962.   if (!x.initialized() || !y.initialized())
  1963.     x.error("operation on uninitialized Integer");
  1964.   Integer g;
  1965.   if (sign(x) == 0 || sign(y) == 0)
  1966.     g = 1;
  1967.   else 
  1968.     g = gcd(x, y);
  1969.   div(x, g, r);
  1970.   mul(r, y, r);
  1971.   return r;
  1972. }
  1973.  
  1974. #endif
  1975.  
  1976.  
  1977.  
  1978. IntRep* atoIntRep(const char* s, int base)
  1979. {
  1980.   int sl = strlen(s);
  1981.   IntRep* r = Icalloc(0, sl * (lg(base) + 1) / I_SHIFT + 1);
  1982.   if (s != 0)
  1983.   {
  1984.     char sgn;
  1985.     while (isspace(*s)) ++s;
  1986.     if (*s == '-')
  1987.     {
  1988.       sgn = I_NEGATIVE;
  1989.       s++;
  1990.     }
  1991.     else if (*s == '+')
  1992.     {
  1993.       sgn = I_POSITIVE;
  1994.       s++;
  1995.     }
  1996.     else
  1997.       sgn = I_POSITIVE;
  1998.     for (;;)
  1999.     {
  2000.       long digit;
  2001.       if (*s >= '0' && *s <= '9') digit = *s - '0';
  2002.       else if (*s >= 'a' && *s <= 'z') digit = *s - 'a' + 10;
  2003.       else if (*s >= 'A' && *s <= 'Z') digit = *s - 'A' + 10;
  2004.       else break;
  2005.       if (digit >= base) break;
  2006.       r = multiply(r, base, r);
  2007.       r = add(r, 0, digit, r);
  2008.       ++s;
  2009.     }
  2010.     r->sgn = sgn;
  2011.   }
  2012.   return r;
  2013. }
  2014.  
  2015.  
  2016.  
  2017. extern AllocRing _libgxx_fmtq;
  2018.  
  2019. char* Itoa(const IntRep* x, int base, int width)
  2020. {
  2021.   int fmtlen = (x->len + 1) * I_SHIFT / lg(base) + 4 + width;
  2022.   char* fmtbase = (char *) _libgxx_fmtq.alloc(fmtlen);
  2023.   char* f = cvtItoa(x, fmtbase, fmtlen, base, 0, width, 0, ' ', 'X', 0);
  2024.   return f;
  2025. }
  2026.  
  2027. ostream& operator << (ostream& s, const Integer& y)
  2028. {
  2029. #ifdef _OLD_STREAMS
  2030.   return s << Itoa(y.rep);
  2031. #else
  2032.   if (s.opfx())
  2033.     {
  2034.       int base = (s.flags() & ios::oct) ? 8 : (s.flags() & ios::hex) ? 16 : 10;
  2035.       int width = s.width();
  2036.       y.printon(s, base, width);
  2037.     }
  2038.   return s;
  2039. #endif
  2040. }
  2041.  
  2042. void Integer::printon(ostream& s, int base /* =10 */, int width /* =0 */) const
  2043. {
  2044.   int align_right = !(s.flags() & ios::left);
  2045.   int showpos = s.flags() & ios::showpos;
  2046.   int showbase = s.flags() & ios::showbase;
  2047.   char fillchar = s.fill();
  2048.   char Xcase = (s.flags() & ios::uppercase)? 'X' : 'x';
  2049.   const IntRep* x = rep;
  2050.   int fmtlen = (x->len + 1) * I_SHIFT / lg(base) + 4 + width;
  2051.   char* fmtbase = new char[fmtlen];
  2052.   char* f = cvtItoa(x, fmtbase, fmtlen, base, showbase, width, align_right,
  2053.             fillchar, Xcase, showpos);
  2054.   s.write(f, fmtlen);
  2055.   delete fmtbase;
  2056. }
  2057.  
  2058. char*  cvtItoa(const IntRep* x, char* fmt, int& fmtlen, int base, int showbase,
  2059.               int width, int align_right, char fillchar, char Xcase, 
  2060.               int showpos)
  2061. {
  2062.   char* e = fmt + fmtlen - 1;
  2063.   char* s = e;
  2064.   *--s = 0;
  2065.  
  2066.   if (x->len == 0)
  2067.     *--s = '0';
  2068.   else
  2069.   {
  2070.     IntRep* z = Icopy(0, x);
  2071.  
  2072.     // split division by base into two parts: 
  2073.     // first divide by biggest power of base that fits in an unsigned short,
  2074.     // then use straight signed div/mods from there. 
  2075.  
  2076.     // find power
  2077.     int bpower = 1;
  2078.     unsigned short b = base;
  2079.     unsigned short maxb = I_MAXNUM / base;
  2080.     while (b < maxb)
  2081.     {
  2082.       b *= base;
  2083.       ++bpower;
  2084.     }
  2085.     for(;;)
  2086.     {
  2087.       int rem = unscale(z->s, z->len, b, z->s);
  2088.       Icheck(z);
  2089.       if (z->len == 0)
  2090.       {
  2091.         while (rem != 0)
  2092.         {
  2093.           char ch = rem % base;
  2094.           rem /= base;
  2095.           if (ch >= 10)
  2096.             ch += 'a' - 10;
  2097.           else
  2098.             ch += '0';
  2099.           *--s = ch;
  2100.         }
  2101.     if (!STATIC_IntRep(z)) delete z;
  2102.         break;
  2103.       }
  2104.       else
  2105.       {
  2106.         for (int i = 0; i < bpower; ++i)
  2107.         {
  2108.           char ch = rem % base;
  2109.           rem /= base;
  2110.           if (ch >= 10)
  2111.             ch += 'a' - 10;
  2112.           else
  2113.             ch += '0';
  2114.           *--s = ch;
  2115.         }
  2116.       }
  2117.     }
  2118.   }
  2119.  
  2120.   if (base == 8 && showbase) 
  2121.     *--s = '0';
  2122.   else if (base == 16 && showbase) 
  2123.   { 
  2124.     *--s = Xcase; 
  2125.     *--s = '0'; 
  2126.   }
  2127.   if (x->sgn == I_NEGATIVE) *--s = '-';
  2128.   else if (showpos) *--s = '+';
  2129.   int w = e - s - 1;
  2130.   if (!align_right || w >= width)
  2131.   {
  2132.     while (w++ < width)
  2133.       *--s = fillchar;
  2134.     fmtlen = e - s - 1;
  2135.     return s;
  2136.   }
  2137.   else
  2138.   {
  2139.     char* p = fmt;
  2140.     for (char* t = s; *t != 0; ++t, ++p) *p = *t;
  2141.     while (w++ < width) *p++ = fillchar;
  2142.     *p = 0;
  2143.     fmtlen = p - fmt;
  2144.     return fmt;
  2145.   }
  2146. }
  2147.  
  2148. char* dec(const Integer& x, int width)
  2149. {
  2150.   return Itoa(x, 10, width);
  2151. }
  2152.  
  2153. char* oct(const Integer& x, int width)
  2154. {
  2155.   return Itoa(x, 8, width);
  2156. }
  2157.  
  2158. char* hex(const Integer& x, int width)
  2159. {
  2160.   return Itoa(x, 16, width);
  2161. }
  2162.  
  2163. istream& operator >> (istream& stream, Integer& val)
  2164. {
  2165.   if (!stream.ipfx0())
  2166.     return stream;
  2167.   int sign = ' ';
  2168.   register streambuf* sb = stream.rdbuf();
  2169.   int base = 10;
  2170.   int ndigits = 0;
  2171.   register int ch = sb->sbumpc();
  2172.   while (ch != EOF && isspace(ch))
  2173.     ch = sb->sbumpc();
  2174.   if (ch == '+' || ch == '-')
  2175.     {
  2176.       sign = ch;
  2177.       ch = sb->sbumpc();
  2178.       while (ch != EOF && isspace(ch))
  2179.     ch = sb->sbumpc();
  2180.     }
  2181.   if (ch == EOF) goto eof_fail;
  2182.   if (!(stream.flags() & ios::basefield))
  2183.     {
  2184.       if (ch == '0')
  2185.     {
  2186.       ch = sb->sbumpc();
  2187.       if (ch == EOF) { }
  2188.       else if (ch == 'x' || ch == 'X')
  2189.         {
  2190.           base = 16;
  2191.           ch = sb->sbumpc();
  2192.           if (ch == EOF) goto eof_fail;
  2193.         }
  2194.       else
  2195.         {
  2196.           sb->sputbackc(ch);
  2197.           base = 8;
  2198.           ch = '0';
  2199.         }
  2200.     }
  2201.     }
  2202.   else if ((stream.flags() & ios::basefield) == ios::hex)
  2203.     base = 16;
  2204.   else if ((stream.flags() & ios::basefield) == ios::oct)
  2205.     base = 8;
  2206.  
  2207.   val.rep = Icopy_zero(val.rep);
  2208.  
  2209.   for (;;)
  2210.     {
  2211.       if (ch == EOF)
  2212.     break;
  2213.       int digit;
  2214.       if (ch >= '0' && ch <= '9')
  2215.     digit = ch - '0';
  2216.       else if (ch >= 'A' && ch <= 'F')
  2217.     digit = ch - 'A' + 10;
  2218.       else if (ch >= 'a' && ch <= 'f')
  2219.     digit = ch - 'a' + 10;
  2220.       else
  2221.     digit = 999;
  2222.       if (digit >= base)
  2223.     {
  2224.       sb->sputbackc(ch);
  2225.       if (ndigits == 0)
  2226.         goto fail;
  2227.       else
  2228.         goto done;
  2229.     }
  2230.       ndigits++;
  2231.       switch (base)
  2232.     {
  2233.     case 8:
  2234.       val <<= 3;
  2235.       break;
  2236.     case 16:
  2237.       val <<= 4;
  2238.       break;
  2239.     default:
  2240.       val *= base;
  2241.       break;
  2242.     }
  2243.       val += digit;
  2244.       ch = sb->sbumpc();
  2245.     }
  2246.  fail:
  2247.   stream.set(ios::failbit);
  2248.  done:
  2249.   if (sign == '-')
  2250.     val.negate();
  2251.   return stream;
  2252.  eof_fail:
  2253.   stream.set(ios::failbit|ios::eofbit);
  2254.   return stream;
  2255. }
  2256.  
  2257. int Integer::OK() const
  2258. {
  2259.   if (rep != 0)
  2260.     {
  2261.       int l = rep->len;
  2262.       int s = rep->sgn;
  2263.       int v = l <= rep->sz || STATIC_IntRep(rep);    // length within bounds
  2264.       v &= s == 0 || s == 1;        // legal sign
  2265.       Icheck(rep);                  // and correctly adjusted
  2266.       v &= rep->len == l;
  2267.       v &= rep->sgn == s;
  2268.       if (v)
  2269.       return v;
  2270.     }
  2271.   error("invariant failure");
  2272.   return 0;
  2273. }
  2274.  
  2275. void Integer::error(const char* msg) const
  2276. {
  2277.   (*lib_error_handler)("Integer", msg);
  2278. }
  2279.  
  2280.